--------------------------------------------------------------------------------------------------------------------
      name:  <unnamed>
       log:  C:\Users\wb614536\Downloads\replication\replication\code\../outputs/08_LeeBounds_W2_log.txt
  log type:  text
 opened on:  25 Jun 2026, 12:59:43
r; t=0.00 12:59:43

. 
. di "=================================================================="
==================================================================
r; t=0.00 12:59:43

. di "  08_LeeBounds_W2.do"
  08_LeeBounds_W2.do
r; t=0.00 12:59:43

. di "=================================================================="
==================================================================
r; t=0.00 12:59:43

. 
. use "$clean/PEP_Analysis_Sample.dta", clear
(PEP analysis sample (JEEA-style + extended outcome indices))
r; t=0.11 12:59:43

. 
. * JEEA-style sample
. local jeea_controls hhven_spouse hhven_other jobopp labven ///
>                     typeworkven1 typeworkven2 typeworkven3 ///
>                     written_cont average yrseduc healthmig frdfam ///
>                     smartven owner electven waterven sewageven female ///
>                     age_panel child_venez time_col
r; t=0.00 12:59:43

. gen sample_roster = .
(13,580 missing values generated)
r; t=0.00 12:59:43

. qui reg trt_hh `jeea_controls'
r; t=2.24 12:59:46

. replace sample_roster = e(sample)
(13,580 real changes made)
r; t=0.00 12:59:46

. replace sample_roster = 0 if gasto_capita == . & trt_hh != .
(119 real changes made)
r; t=0.00 12:59:46

. replace sample_roster = 0 if employed == . & trt_hh != .
(88 real changes made)
r; t=0.00 12:59:46

. replace sample_roster = 0 if hora_semana == . & trt_hh != . & asalariado_num == 1
(64 real changes made)
r; t=0.00 12:59:46

. replace sample_roster = 0 if anx_depr == .
(2 real changes made)
r; t=0.00 12:59:46

. replace sample_roster = 0 if health_pca == .
(8 real changes made)
r; t=0.00 12:59:46

. bysort family_id: egen sample_reg = max(sample_roster)
r; t=0.01 12:59:46

. keep if (orden == 1 | orden == 2) & sample_reg == 1
(6,451 observations deleted)
r; t=0.02 12:59:46

. keep if wave_num == 2
(4,328 observations deleted)
r; t=0.01 12:59:46

. 
. * Build mental-health and trust composites on the fly (mirrors 07_RD_W1_W2.do)
. foreach src in life_satisfaction hi5_inv any_anx_depr vas_score general_trust trust_col trust_ven {
  2.     capture drop _z_`src'
  3.     gen _z_`src' = .
  4.     qui sum `src' if pep == 0
  5.     if r(N) > 0 & r(sd) > 0 {
  6.         replace _z_`src' = (`src' - r(mean)) / r(sd)
  7.     }
  8. }
(2,801 missing values generated)
(2,794 real changes made)
(2,801 missing values generated)
(2,796 real changes made)
(2,801 missing values generated)
(2,796 real changes made)
(2,801 missing values generated)
(2,794 real changes made)
(2,801 missing values generated)
(2,660 real changes made)
(2,801 missing values generated)
(1,325 real changes made)
(2,801 missing values generated)
(1,331 real changes made)
r; t=0.02 12:59:46

. replace _z_any_anx_depr = -_z_any_anx_depr
(2,796 real changes made)
r; t=0.00 12:59:46

. egen mh_raw    = rowmean(_z_life_satisfaction _z_hi5_inv _z_any_anx_depr _z_vas_score)
(5 missing values generated)
r; t=0.01 12:59:46

. egen trust_raw = rowmean(_z_general_trust _z_trust_col _z_trust_ven)
(140 missing values generated)
r; t=0.00 12:59:46

. capture drop mh_index
r; t=0.00 12:59:46

. capture drop trust_index
r; t=0.00 12:59:46

. gen mh_index    = .
(2,801 missing values generated)
r; t=0.00 12:59:46

. gen trust_index = .
(2,801 missing values generated)
r; t=0.00 12:59:46

. qui sum mh_raw if pep == 0
r; t=0.00 12:59:46

. if r(N) > 0 & r(sd) > 0 replace mh_index = (mh_raw - r(mean)) / r(sd)
(2,796 real changes made)
r; t=0.00 12:59:46
r; t=0.00 12:59:46

. qui sum trust_raw if pep == 0
r; t=0.00 12:59:46

. if r(N) > 0 & r(sd) > 0 replace trust_index = (trust_raw - r(mean)) / r(sd)
(2,661 real changes made)
r; t=0.00 12:59:46
r; t=0.00 12:59:46

. drop _z_* mh_raw trust_raw
r; t=0.00 12:59:46

. 
. di ""

r; t=0.00 12:59:46

. di "  W2 JEEA sample size: " _N
  W2 JEEA sample size: 2801
r; t=0.00 12:59:46

. 
. * Headline outcomes for Lee bounds. Eight thematic indices plus
. * underlying components (the 8th panel is mental health via mh_index).
. local lee_outcomes ///
>     jeea_index_wellbeing labour_income gasto_capita income_maxhh employed ///
>     jeea_index_labor formal hora_semana ///
>     jeea_index_services sisben subs govtr ///
>     health_pca anx_depr mh_index life_satisfaction hi5_inv vas_score ///
>     index_food skip_meals went_without_food protein_days ///
>     index_housing adequate_housing has_electricity has_water has_sewage ///
>     index_integration belonging feel_integrated col_friends community_org connection_colombia ///
>     trust_index general_trust trust_col trust_ven ///
>     index_discrim discrim_ever ///
>     index_covid covid_received_aid ///
>     index_remit remit_now ///
>     index_fin_access index_digital
r; t=0.00 12:59:46

. 
. local lee_treats ///
>     pep    pep    trt_hh trt_hh pep ///
>     pep    pep    pep ///
>     pep    pep    pep    trt_hh ///
>     pep    pep    pep    pep    pep    pep ///
>     pep    pep    pep    pep ///
>     pep    pep    pep    pep    pep ///
>     pep    pep    pep    pep    pep    pep ///
>     pep    pep    pep    pep ///
>     pep    pep ///
>     trt_hh trt_hh ///
>     trt_hh trt_hh ///
>     trt_hh trt_hh
r; t=0.00 12:59:46

. 
. local n_lee : word count `lee_outcomes'
r; t=0.00 12:59:46

. di "  Outcomes for Lee bounds: `n_lee'"
  Outcomes for Lee bounds: 45
r; t=0.00 12:59:46

. assert `n_lee' == `: word count `lee_treats''
r; t=0.00 12:59:46

. 
. /*==============================================================================
>   IMPLEMENT LEE BOUNDS
> ==============================================================================*/
. 
. * Trimming proportion q = 1 - (n_smaller / n_larger) within the optimal bw.
. * Determine which side of the cutoff has fewer obs (in our case, ineligible /
. * daterd > 0 should be smaller after attrition). Then trim that fraction of
. * the LARGER side from top (upper bound) and bottom (lower bound) of the
. * outcome distribution. Refit rdrobust on the trimmed sample.
. 
. capture program drop _lee_bounds
r; t=0.00 12:59:46

. program define _lee_bounds, rclass
  1.     args outcome treatment
  2.     local b_pt    = .
  3.     local b_lower = .
  4.     local b_upper = .
  5.     local n_pt    = .
  6.     local h       = .
  7. 
.     * Step 1: optimal-bandwidth point estimate
.     capture rdrobust `outcome' date, c(0) fuzzy(`treatment') ///
>         kernel(triangular) bwselect(mserd) p(1) all
  8.     if _rc {
  9.         return scalar pt = .
 10.         return scalar lo = .
 11.         return scalar hi = .
 12.         return scalar n  = .
 13.         return scalar trim_q = .
 14.         exit
 15.     }
 16.     local b_pt = e(tau_cl)
 17.     local h    = e(h_l)
 18.     local n_pt = e(N_h_l) + e(N_h_r)
 19. 
.     qui count if date > 0 & date <= `h' & !missing(`outcome')
 20.     local n_above = r(N)
 21.     qui count if date < 0 & date >= -`h' & !missing(`outcome')
 22.     local n_below = r(N)
 23. 
.     if `n_above' == 0 | `n_below' == 0 {
 24.         return scalar pt = `b_pt'
 25.         return scalar lo = .
 26.         return scalar hi = .
 27.         return scalar n  = `n_pt'
 28.         return scalar trim_q = .
 29.         exit
 30.     }
 31. 
.     local n_diff = abs(`n_above' - `n_below')
 32.     local q = `n_diff' / max(`n_above', `n_below')
 33. 
.     if `n_diff' == 0 {
 34.         return scalar pt = `b_pt'
 35.         return scalar lo = `b_pt'
 36.         return scalar hi = `b_pt'
 37.         return scalar n  = `n_pt'
 38.         return scalar trim_q = 0
 39.         exit
 40.     }
 41. 
.     * Choose which side to trim
.     if `n_above' > `n_below' local trim_cond  "date > 0 & date <= `h'"
 42.     else                     local trim_cond  "date < 0 & date >= -`h'"
 43. 
.     * Rank observations on the trim side by outcome (ascending)
.     capture drop __rk
 44.     egen __rk = rank(`outcome') if `trim_cond' & !missing(`outcome'), unique
 45.     qui sum __rk
 46.     local max_rk = r(max)
 47. 
.     * Lower bound: drop the TOP n_diff (highest-outcome) obs from the trim side
.     *   → biases the kept sample toward LOWER outcomes on the over-side.
.     * Upper bound: drop the BOTTOM n_diff (lowest-outcome) obs.
.     capture drop __keep_lo __keep_hi
 48.     gen __keep_lo = 1
 49.     gen __keep_hi = 1
 50.     replace __keep_lo = 0 if __rk > `max_rk' - `n_diff' & !missing(__rk)
 51.     replace __keep_hi = 0 if __rk <= `n_diff'                & !missing(__rk)
 52. 
.     capture rdrobust `outcome' date if __keep_lo == 1, c(0) fuzzy(`treatment') ///
>         kernel(triangular) h(`h') p(1) all
 53.     if !_rc local b_lower = e(tau_cl)
 54.     capture rdrobust `outcome' date if __keep_hi == 1, c(0) fuzzy(`treatment') ///
>         kernel(triangular) h(`h') p(1) all
 55.     if !_rc local b_upper = e(tau_cl)
 56. 
.     drop __rk __keep_lo __keep_hi
 57. 
.     return scalar pt = `b_pt'
 58.     return scalar lo = `b_lower'
 59.     return scalar hi = `b_upper'
 60.     return scalar n  = `n_pt'
 61.     return scalar trim_q = `q'
 62. end
r; t=0.00 12:59:46

. 
. * Run for each outcome
. file open lee using "$out/08_LeeBounds_W2_results.txt", write replace text
(file ../outputs/08_LeeBounds_W2_results.txt not found)
r; t=0.00 12:59:46

. file write lee "outcome" _tab "treatment" _tab "point" _tab "lower" _tab "upper" _tab "trim_q" _tab "n_eff" _newli
> ne
r; t=0.00 12:59:46

. 
. tempname LEE
r; t=0.00 12:59:46

. matrix `LEE' = J(`n_lee', 5, .)
r; t=0.00 12:59:46

. forvalues k = 1/`n_lee' {
  2.     local v   : word `k' of `lee_outcomes'
  3.     local trt : word `k' of `lee_treats'
  4.     capture confirm variable `v'
  5.     if _rc continue
  6. 
.     _lee_bounds `v' `trt'
  7.     local pt   = r(pt)
  8.     local lo   = r(lo)
  9.     local hi   = r(hi)
 10.     local q    = r(trim_q)
 11.     local n    = r(n)
 12. 
.     matrix `LEE'[`k', 1] = `pt'
 13.     matrix `LEE'[`k', 2] = `lo'
 14.     matrix `LEE'[`k', 3] = `hi'
 15.     matrix `LEE'[`k', 4] = `q'
 16.     matrix `LEE'[`k', 5] = `n'
 17. 
.     file write lee "`v'" _tab "`trt'" _tab "`=string(`pt', "%6.3f")'" _tab
 18.     file write lee "`=string(`lo', "%6.3f")'" _tab "`=string(`hi', "%6.3f")'" _tab
 19.     file write lee "`=string(`q', "%5.3f")'" _tab "`n'" _newline
 20. 
.     di %-30s "`v'" %5s "`trt'" %10.3f `pt' "  bounds: [" %6.3f `lo' "," %6.3f `hi' "]" "  q=" %5.3f `q'
 21. }
(2,348 missing values generated)
(175 real changes made)
(175 real changes made)
jeea_index_wellbeing            pep     0.554  bounds: [-0.636, 1.497]  q=0.386
(2,556 missing values generated)
(88 real changes made)
(88 real changes made)
labour_income                   pep     0.486  bounds: [ 0.076, 0.749]  q=0.359
(2,314 missing values generated)
(209 real changes made)
(209 real changes made)
gasto_capita                  trt_hh     0.106  bounds: [-0.518, 0.464]  q=0.429
(2,320 missing values generated)
(204 real changes made)
(204 real changes made)
income_maxhh                  trt_hh     0.247  bounds: [-0.146, 0.533]  q=0.424
(2,402 missing values generated)
(161 real changes made)
(161 real changes made)
employed                        pep     0.056  bounds: [-0.414, 0.572]  q=0.404
(2,485 missing values generated)
(146 real changes made)
(146 real changes made)
jeea_index_labor                pep     1.097  bounds: [-0.397, 1.381]  q=0.462
(2,480 missing values generated)
(149 real changes made)
(149 real changes made)
formal                          pep     0.246  bounds: [ 0.023, 0.414]  q=0.464
(2,542 missing values generated)
(107 real changes made)
(107 real changes made)
hora_semana                     pep     0.068  bounds: [-0.428, 0.304]  q=0.413
(2,448 missing values generated)
(127 real changes made)
(127 real changes made)
jeea_index_services             pep     2.425  bounds: [ 2.123, 2.857]  q=0.360
(2,413 missing values generated)
(136 real changes made)
(136 real changes made)
sisben                          pep     0.762  bounds: [ 0.507, 0.910]  q=0.351
(2,423 missing values generated)
(128 real changes made)
(128 real changes made)
subs                            pep     0.454  bounds: [ 0.104, 0.475]  q=0.339
(2,445 missing values generated)
(129 real changes made)
(129 real changes made)
govtr                         trt_hh     0.391  bounds: [ 0.339, 0.524]  q=0.362
(2,401 missing values generated)
(136 real changes made)
(136 real changes made)
health_pca                      pep     0.990  bounds: [-0.073, 1.603]  q=0.340
(2,489 missing values generated)
(115 real changes made)
(115 real changes made)
anx_depr                        pep    -0.035  bounds: [-0.037,-0.027]  q=0.369
(2,290 missing values generated)
(219 real changes made)
(219 real changes made)
mh_index                        pep    -0.121  bounds: [-1.028, 0.549]  q=0.429
(2,431 missing values generated)
(143 real changes made)
(143 real changes made)
life_satisfaction               pep    -0.441  bounds: [-2.783, 1.490]  q=0.386
(2,248 missing values generated)
(237 real changes made)
(237 real changes made)
hi5_inv                         pep     0.080  bounds: [-0.523, 0.648]  q=0.429
(2,395 missing values generated)
(142 real changes made)
(142 real changes made)
vas_score                       pep    -0.660  bounds: [-15.626,12.823]  q=0.350
(2,412 missing values generated)
(142 real changes made)
(142 real changes made)
index_food                      pep     0.596  bounds: [ 0.045, 0.933]  q=0.365
(2,306 missing values generated)
(213 real changes made)
(213 real changes made)
skip_meals                      pep    -0.275  bounds: [-0.556,-0.001]  q=0.430
(2,471 missing values generated)
(112 real changes made)
(112 real changes made)
went_without_food               pep    -0.299  bounds: [-0.489,-0.201]  q=0.339
(2,314 missing values generated)
(207 real changes made)
(207 real changes made)
protein_days                    pep     2.312  bounds: [ 0.405, 4.569]  q=0.425
(2,401 missing values generated)
(134 real changes made)
(134 real changes made)
index_housing                   pep     1.086  bounds: [ 1.045, 1.206]  q=0.335
(2,310 missing values generated)
(209 real changes made)
(209 real changes made)
adequate_housing                pep     0.493  bounds: [ 0.335, 0.730]  q=0.426
(2,311 missing values generated)
(213 real changes made)
(213 real changes made)
has_electricity                 pep     0.062  bounds: [ 0.069, 0.047]  q=0.435
(2,406 missing values generated)
(134 real changes made)
(134 real changes made)
has_water                       pep     0.038  bounds: [ 0.013, 0.084]  q=0.339
(2,345 missing values generated)
(183 real changes made)
(183 real changes made)
has_sewage                      pep     0.353  bounds: [ 0.364, 0.330]  q=0.401
(2,368 missing values generated)
(169 real changes made)
(169 real changes made)
index_integration               pep     0.833  bounds: [ 0.073, 1.132]  q=0.390
(2,463 missing values generated)
(126 real changes made)
(126 real changes made)
belonging                       pep     1.418  bounds: [ 0.714, 2.175]  q=0.373
(2,463 missing values generated)
(126 real changes made)
(126 real changes made)
feel_integrated                 pep     0.974  bounds: [ 0.076, 1.341]  q=0.373
(2,304 missing values generated)
(217 real changes made)
(217 real changes made)
col_friends                     pep     0.969  bounds: [-0.240, 2.139]  q=0.437
(2,328 missing values generated)
(205 real changes made)
(205 real changes made)
community_org                   pep     0.010  bounds: [-0.085, 0.062]  q=0.433
(2,304 missing values generated)
(217 real changes made)
(217 real changes made)
connection_colombia             pep     0.987  bounds: [ 0.003, 1.538]  q=0.437
(2,471 missing values generated)
(120 real changes made)
(120 real changes made)
trust_index                     pep     0.814  bounds: [ 0.185, 1.558]  q=0.364
(2,427 missing values generated)
(130 real changes made)
(130 real changes made)
general_trust                   pep     0.636  bounds: [ 0.063, 1.730]  q=0.348
(2,600 missing values generated)
(66 real changes made)
(66 real changes made)
trust_col                       pep     0.555  bounds: [ 0.103, 1.384]  q=0.328
(2,564 missing values generated)
(94 real changes made)
(94 real changes made)
trust_ven                       pep     0.972  bounds: [ 0.049, 1.303]  q=0.397
(2,260 missing values generated)
(237 real changes made)
(237 real changes made)
index_discrim                   pep    -0.135  bounds: [-0.930, 0.664]  q=0.438
(2,294 missing values generated)
(225 real changes made)
(225 real changes made)
discrim_ever                    pep    -0.209  bounds: [-0.790, 0.335]  q=0.444
(2,550 missing values generated)
(95 real changes made)
(95 real changes made)
index_covid                   trt_hh     0.627  bounds: [ 0.212, 1.098]  q=0.378
(2,212 missing values generated)
(268 real changes made)
(268 real changes made)
covid_received_aid            trt_hh    -0.235  bounds: [-0.624, 0.283]  q=0.455
(2,221 missing values generated)
(255 real changes made)
(255 real changes made)
index_remit                   trt_hh     0.092  bounds: [-0.332, 0.553]  q=0.440
(2,284 missing values generated)
(225 real changes made)
(225 real changes made)
remit_now                     trt_hh     0.027  bounds: [-0.535, 0.310]  q=0.435
(2,310 missing values generated)
(209 real changes made)
(209 real changes made)
index_fin_access              trt_hh    -0.097  bounds: [-0.891, 0.633]  q=0.426
(2,471 missing values generated)
(114 real changes made)
(114 real changes made)
index_digital                 trt_hh    -0.133  bounds: [-0.441, 0.233]  q=0.345
r; t=28.88 13:00:15

. file close lee
r; t=0.00 13:00:15

. 
. /*==============================================================================
>   PDF
> ==============================================================================*/
. 
. putpdf clear
r; t=0.04 13:00:15

. putpdf begin
r; t=0.01 13:00:15

. putpdf paragraph, halign(center)
r; t=0.04 13:00:15

. putpdf text ("Lee Bounds — Wave 2"), bold font(, 16)
r; t=0.02 13:00:15

. putpdf paragraph, halign(center)
r; t=0.04 13:00:15

. putpdf text ("Sensitivity to differential attrition. $S_DATE."), italic
r; t=0.00 13:00:15

. 
. putpdf paragraph
r; t=0.00 13:00:15

. putpdf text ("Method: trim the over-represented side at the cutoff to equalize sample sizes; refit rdrobust at the
>  optimal bandwidth. Bounds bracket the true LATE under monotonic selection."), italic font(, 10)
r; t=0.00 13:00:15

. 
. * Stash tempname matrix into a globally-named matrix so the loop below can use it
. matrix LEE = `LEE'
r; t=0.00 13:00:15

. 
. putpdf table lt = (`=`n_lee'+1', 6), border(all)
r; t=0.02 13:00:15

. putpdf table lt(1,1) = ("Outcome"), bold halign(center)
r; t=0.01 13:00:15

. putpdf table lt(1,2) = ("Trt"), bold halign(center)
r; t=0.00 13:00:15

. putpdf table lt(1,3) = ("Point"), bold halign(center)
r; t=0.00 13:00:15

. putpdf table lt(1,4) = ("Lower"), bold halign(center)
r; t=0.00 13:00:15

. putpdf table lt(1,5) = ("Upper"), bold halign(center)
r; t=0.00 13:00:15

. putpdf table lt(1,6) = ("Trim q"), bold halign(center)
r; t=0.00 13:00:15

. 
. forvalues k = 1/`n_lee' {
  2.     local v   : word `k' of `lee_outcomes'
  3.     local trt : word `k' of `lee_treats'
  4.     local row = `k' + 1
  5.     local pt = LEE[`k', 1]
  6.     local lo = LEE[`k', 2]
  7.     local hi = LEE[`k', 3]
  8.     local q  = LEE[`k', 4]
  9.     putpdf table lt(`row',1) = ("`v'"), font("Courier", 8)
 10.     putpdf table lt(`row',2) = ("`trt'"), font(, 8)
 11.     putpdf table lt(`row',3) = ("`=string(`pt', "%5.3f")'"), font(, 8)
 12.     putpdf table lt(`row',4) = ("`=string(`lo', "%5.3f")'"), font(, 8)
 13.     putpdf table lt(`row',5) = ("`=string(`hi', "%5.3f")'"), font(, 8)
 14.     putpdf table lt(`row',6) = ("`=string(`q', "%5.3f")'"), font(, 8)
 15. }
r; t=0.15 13:00:15

. 
. putpdf save "$out/08_LeeBounds_W2.pdf", replace
successfully created "C:/Users/wb614536/Downloads/replication/replication/outputs/08_LeeBounds_W2.pdf"
r; t=0.04 13:00:15

. 
. * LaTeX skeleton
. file open tex using "$out/08_LeeBounds_W2.tex", write replace
(file ../outputs/08_LeeBounds_W2.tex not found)
r; t=0.00 13:00:15

. file write tex "\documentclass[11pt]{article}\usepackage[margin=1in]{geometry}\usepackage{booktabs}" _n
r; t=0.00 13:00:15

. file write tex "\title{Lee Bounds (Wave 2)}\author{Sandra Rozo}\date{\today}\begin{document}\maketitle" _n
r; t=0.00 13:00:15

. file write tex "Lee bounds for W2 fuzzy-RD estimates. See 08\_LeeBounds\_W2.pdf." _n
r; t=0.00 13:00:15

. file write tex "\end{document}" _n
r; t=0.00 13:00:15

. file close tex
r; t=0.00 13:00:15

. 
. di ""

r; t=0.00 13:00:15

. di "  PDF saved:    $out/08_LeeBounds_W2.pdf"
  PDF saved:    ../outputs/08_LeeBounds_W2.pdf
r; t=0.00 13:00:15

. di "  TeX saved:    $out/08_LeeBounds_W2.tex"
  TeX saved:    ../outputs/08_LeeBounds_W2.tex
r; t=0.00 13:00:15

. di "  Results:      $out/08_LeeBounds_W2_results.txt"
  Results:      ../outputs/08_LeeBounds_W2_results.txt
r; t=0.00 13:00:15

. di "  Done."
  Done.
r; t=0.00 13:00:15

. 
. log close
      name:  <unnamed>
       log:  C:\Users\wb614536\Downloads\replication\replication\code\../outputs/08_LeeBounds_W2_log.txt
  log type:  text
 closed on:  25 Jun 2026, 13:00:15
--------------------------------------------------------------------------------------------------------------------
